<template>
  <div class="gantt-chart-container">
    <!-- 工具栏 -->
    <div class="gantt-toolbar">
      <div class="toolbar-left">
        <el-select v-model="viewMode" size="small" style="width: 120px;">
          <el-option label="按设备" value="device" />
          <el-option label="按订单" value="order" />
        </el-select>
        <el-date-picker
          v-model="dateRange"
          type="daterange"
          size="small"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          value-format="YYYY-MM-DD"
          style="margin-left: 10px;"
        />
      </div>
      <div class="toolbar-right">
        <el-button size="small" @click="zoomIn">
          <el-icon><ZoomIn /></el-icon>
        </el-button>
        <el-button size="small" @click="zoomOut">
          <el-icon><ZoomOut /></el-icon>
        </el-button>
        <el-button size="small" @click="resetZoom">
          <el-icon><Refresh /></el-icon>
          重置
        </el-button>
      </div>
    </div>

    <!-- 甘特图主体 -->
    <div ref="ganttChartRef" class="gantt-chart-main" :style="{ height: height + 'px' }"></div>

    <!-- 图例 -->
    <div class="gantt-legend">
      <div class="legend-item">
        <span class="legend-color" style="background: #409eff;"></span>
        <span class="legend-label">进行中</span>
      </div>
      <div class="legend-item">
        <span class="legend-color" style="background: #67c23a;"></span>
        <span class="legend-label">已完成</span>
      </div>
      <div class="legend-item">
        <span class="legend-color" style="background: #e6a23c;"></span>
        <span class="legend-label">待开始</span>
      </div>
      <div class="legend-item">
        <span class="legend-color" style="background: #f56c6c;"></span>
        <span class="legend-label">延期</span>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, onMounted, watch, nextTick } from 'vue'
import * as echarts from 'echarts'
import { ZoomIn, ZoomOut, Refresh } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

export default {
  name: 'GanttChart',
  components: {
    ZoomIn,
    ZoomOut,
    Refresh
  },
  props: {
    // 甘特图数据
    chartData: {
      type: Array,
      required: true,
      default: () => []
    },
    // 约束 ID
    constraintId: {
      type: String,
      default: ''
    },
    // 图表高度
    height: {
      type: Number,
      default: 400
    }
  },
  setup(props) {
    // 甘特图 DOM 引用
    const ganttChartRef = ref(null)
    
    // ECharts 实例
    let chartInstance = null
    
    // 视图模式：按设备或按订单
    const viewMode = ref('device')
    
    // 日期范围
    const dateRange = ref([])
    
    // 缩放级别
    const zoomLevel = ref(100)

    /**
     * 初始化甘特图
     */
    const initGanttChart = () => {
      if (!ganttChartRef.value) return

      // 销毁旧实例
      if (chartInstance) {
        chartInstance.dispose()
      }

      // 创建新实例
      chartInstance = echarts.init(ganttChartRef.value)

      // 渲染图表
      renderChart()

      // 监听窗口大小变化
      window.addEventListener('resize', handleResize)
    }

    /**
     * 渲染图表
     */
    const renderChart = () => {
      if (!chartInstance || !props.chartData || props.chartData.length === 0) {
        return
      }

      // 根据视图模式转换数据
      const { categories, series } = viewMode.value === 'device' 
        ? transformDeviceData(props.chartData)
        : transformOrderData(props.chartData)

      // 配置 ECharts 选项
      const option = {
        tooltip: {
          formatter: (params) => {
            const data = params.data
            return `
              <div style="padding: 8px;">
                <div><strong>${data.name}</strong></div>
                <div>开始: ${data.startTime}</div>
                <div>结束: ${data.endTime}</div>
                <div>工时: ${data.duration}h</div>
                <div>订单: ${data.orderCode}</div>
                <div>产品: ${data.productCode}</div>
              </div>
            `
          }
        },
        grid: {
          left: 150,
          right: 50,
          top: 50,
          bottom: 50,
          containLabel: true
        },
        xAxis: {
          type: 'time',
          axisLabel: {
            formatter: '{MM}-{dd} {HH}:{mm}'
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: '#e4e7ed',
              type: 'dashed'
            }
          }
        },
        yAxis: {
          type: 'category',
          data: categories,
          axisLabel: {
            fontSize: 12,
            color: '#606266'
          },
          axisTick: {
            show: false
          },
          axisLine: {
            show: true,
            lineStyle: {
              color: '#dcdfe6'
            }
          }
        },
        dataZoom: [
          {
            type: 'slider',
            filterMode: 'none',
            showDataShadow: false,
            top: 10,
            height: 20,
            borderColor: 'transparent',
            backgroundColor: '#e2e2e2',
            handleIcon: 'path://M10.7,11.9H9.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z',
            handleSize: '100%',
            handleStyle: {
              color: '#fff',
              shadowBlur: 4,
              shadowColor: 'rgba(0, 0, 0, 0.3)',
              shadowOffsetX: 1,
              shadowOffsetY: 1
            },
            textStyle: {
              color: '#333'
            }
          },
          {
            type: 'inside',
            filterMode: 'none'
          }
        ],
        series: series
      }

      chartInstance.setOption(option)
    }

    /**
     * 转换设备视图数据
     */
    const transformDeviceData = (data) => {
      const categories = []
      const seriesData = []

      data.forEach(device => {
        categories.push(device.deviceName || device.deviceCode)
        
        if (device.tasks && device.tasks.length > 0) {
          device.tasks.forEach(task => {
            seriesData.push({
              name: task.orderCode,
              value: [
                categories.length - 1,
                new Date(task.startTime).getTime(),
                new Date(task.endTime).getTime(),
                task.duration
              ],
              itemStyle: {
                color: getTaskColor(task)
              },
              // 附加数据用于 tooltip
              startTime: task.startTime,
              endTime: task.endTime,
              duration: task.duration,
              orderCode: task.orderCode,
              productCode: task.productCode
            })
          })
        }
      })

      return {
        categories,
        series: [{
          type: 'custom',
          renderItem: renderGanttItem,
          encode: {
            x: [1, 2],
            y: 0
          },
          data: seriesData
        }]
      }
    }

    /**
     * 转换订单视图数据
     */
    const transformOrderData = (data) => {
      // TODO: 实现按订单分组的数据转换
      // 暂时使用设备视图的数据
      return transformDeviceData(data)
    }

    /**
     * 自定义渲染甘特图条形项
     */
    const renderGanttItem = (params, api) => {
      const categoryIndex = api.value(0)
      const start = api.coord([api.value(1), categoryIndex])
      const end = api.coord([api.value(2), categoryIndex])
      const height = api.size([0, 1])[1] * 0.6

      const rectShape = echarts.graphic.clipRectByRect(
        {
          x: start[0],
          y: start[1] - height / 2,
          width: end[0] - start[0],
          height: height
        },
        {
          x: params.coordSys.x,
          y: params.coordSys.y,
          width: params.coordSys.width,
          height: params.coordSys.height
        }
      )

      return rectShape && {
        type: 'rect',
        transition: ['shape'],
        shape: rectShape,
        style: api.style()
      }
    }

    /**
     * 根据任务状态获取颜色
     */
    const getTaskColor = (task) => {
      const now = new Date()
      const startTime = new Date(task.startTime)
      const endTime = new Date(task.endTime)

      if (now > endTime) {
        return '#67c23a' // 已完成 - 绿色
      } else if (now >= startTime && now <= endTime) {
        return '#409eff' // 进行中 - 蓝色
      } else if (now < startTime) {
        return '#e6a23c' // 待开始 - 橙色
      } else {
        return '#f56c6c' // 延期 - 红色
      }
    }

    /**
     * 放大
     */
    const zoomIn = () => {
      if (zoomLevel.value < 200) {
        zoomLevel.value += 10
        ElMessage.success(`缩放至 ${zoomLevel.value}%`)
      }
    }

    /**
     * 缩小
     */
    const zoomOut = () => {
      if (zoomLevel.value > 50) {
        zoomLevel.value -= 10
        ElMessage.success(`缩放至 ${zoomLevel.value}%`)
      }
    }

    /**
     * 重置缩放
     */
    const resetZoom = () => {
      zoomLevel.value = 100
      if (chartInstance) {
        chartInstance.dispatchAction({
          type: 'dataZoom',
          start: 0,
          end: 100
        })
      }
      ElMessage.success('已重置缩放')
    }

    /**
     * 处理窗口大小变化
     */
    const handleResize = () => {
      if (chartInstance) {
        chartInstance.resize()
      }
    }

    // 监听数据变化
    watch(() => props.chartData, () => {
      nextTick(() => {
        renderChart()
      })
    }, { deep: true })

    // 监听视图模式变化
    watch(viewMode, () => {
      renderChart()
    })

    // 组件挂载
    onMounted(() => {
      nextTick(() => {
        initGanttChart()
      })
    })

    // 组件卸载
    const onBeforeUnmount = () => {
      if (chartInstance) {
        chartInstance.dispose()
        chartInstance = null
      }
      window.removeEventListener('resize', handleResize)
    }

    return {
      ganttChartRef,
      viewMode,
      dateRange,
      zoomLevel,
      zoomIn,
      zoomOut,
      resetZoom,
      onBeforeUnmount
    }
  },
  beforeUnmount() {
    this.onBeforeUnmount()
  }
}
</script>

<style scoped>
.gantt-chart-container {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.gantt-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px;
  background: #f5f7fa;
  border-radius: 8px;
}

.toolbar-left,
.toolbar-right {
  display: flex;
  align-items: center;
  gap: 10px;
}

.gantt-chart-main {
  width: 100%;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  background: white;
}

.gantt-legend {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 20px;
  padding: 10px;
  background: #f5f7fa;
  border-radius: 8px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.legend-color {
  width: 16px;
  height: 16px;
  border-radius: 3px;
}

.legend-label {
  font-size: 13px;
  color: #606266;
}
</style>

